package com.eduplatform.controller;

import com.eduplatform.common.Result;
import com.eduplatform.dto.FileUploadDTO;
import com.eduplatform.service.FileService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 文件上传控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/files")
@RequiredArgsConstructor
public class FileController {

    private final FileService fileService;

    @Value("${file.upload.path:uploads}")
    private String uploadPath;

    @Value("${file.upload.url:http://localhost:8080/uploads}")
    private String fileUrl;

    /**
     * 上传单个文件
     *
     * @param file 文件
     * @return 文件上传响应
     */
    @PostMapping("/upload")
    public Result<Map<String, String>> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            // 检查文件是否为空
            if (file.isEmpty()) {
                return Result.error("文件为空");
            }

            // 创建上传目录
            String uploadDir = uploadPath + "/files";
            createDirectoryIfNotExists(uploadDir);

            // 获取文件名并生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String fileExtension = getFileExtension(originalFilename);
            String newFilename = UUID.randomUUID().toString() + fileExtension;

            // 保存文件
            Path filePath = Paths.get(uploadDir, newFilename);
            Files.write(filePath, file.getBytes());

            // 返回文件URL
            String url = fileUrl + "/files/" + newFilename;
            Map<String, String> response = new HashMap<>();
            response.put("url", url);
            response.put("filename", originalFilename);

            return Result.success(response);
        } catch (IOException e) {
            e.printStackTrace();
            return Result.error("文件上传失败: " + e.getMessage());
        }
    }

    /**
     * 上传封面图
     */
    @PostMapping("/upload-cover")
    public Result<Map<String, String>> uploadCover(@RequestParam("file") MultipartFile file) {
        try {
            // 检查文件是否为空
            if (file.isEmpty()) {
                return Result.error("文件为空");
            }

            // 检查文件类型
            String contentType = file.getContentType();
            if (contentType == null || !contentType.startsWith("image/")) {
                return Result.error("只能上传图片文件");
            }

            // 创建上传目录
            String uploadDir = uploadPath + "/covers";
            createDirectoryIfNotExists(uploadDir);

            // 获取文件名并生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String fileExtension = getFileExtension(originalFilename);
            String newFilename = UUID.randomUUID().toString() + fileExtension;

            // 保存文件
            Path filePath = Paths.get(uploadDir, newFilename);
            Files.write(filePath, file.getBytes());

            // 返回文件URL
            String url = fileUrl + "/covers/" + newFilename;
            Map<String, String> response = new HashMap<>();
            response.put("url", url);
            response.put("filename", originalFilename);

            return Result.success(response);
        } catch (IOException e) {
            e.printStackTrace();
            return Result.error("封面上传失败: " + e.getMessage());
        }
    }

    /**
     * 创建目录（如果不存在）
     */
    private void createDirectoryIfNotExists(String directoryPath) {
        File directory = new File(directoryPath);
        if (!directory.exists()) {
            directory.mkdirs();
        }
    }

    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String filename) {
        if (filename == null) {
            return "";
        }
        int dotIndex = filename.lastIndexOf('.');
        return (dotIndex == -1) ? "" : filename.substring(dotIndex);
    }

    /**
     * 批量上传文件
     *
     * @param files 文件列表
     * @return 文件上传响应列表
     */
    @PostMapping("/batch-upload")
    public Result<List<FileUploadDTO>> uploadFiles(
            @RequestParam("files") List<MultipartFile> files) {
        if (files.isEmpty()) {
            return Result.error("上传的文件不能为空");
        }
        try {
            log.info("开始批量上传文件, 数量: {}", files.size());
            List<String> fileUrls = fileService.uploadFiles(files);
            log.info("批量上传文件成功, 数量: {}", fileUrls.size());

            List<FileUploadDTO> uploadDTOs = new ArrayList<>();
            for (int i = 0; i < files.size(); i++) {
                MultipartFile file = files.get(i);
                String fileUrl = fileUrls.get(i);

                FileUploadDTO uploadDTO = FileUploadDTO.builder()
                        .originalFilename(file.getOriginalFilename())
                        .size(file.getSize())
                        .contentType(file.getContentType())
                        .url(fileUrl)
                        .path(fileUrl.substring(0,
                                fileUrl.indexOf("?") != -1 ? fileUrl.indexOf("?") : fileUrl.length()))
                        .build();

                uploadDTOs.add(uploadDTO);
            }

            return Result.success(uploadDTOs);
        } catch (Exception e) {
            log.error("批量上传文件失败: {}", e.getMessage(), e);
            return Result.error("批量上传文件失败: " + e.getMessage());
        }
    }

    /**
     * 删除文件
     *
     * @param fileUrl 文件URL
     * @return 是否删除成功
     */
    @DeleteMapping
    public Result<Boolean> deleteFile(
            @RequestParam("fileUrl") String fileUrl) {
        try {
            log.info("开始删除文件: {}", fileUrl);
            boolean result = fileService.deleteFile(fileUrl);
            if (result) {
                log.info("文件删除成功: {}", fileUrl);
                return Result.success(true);
            } else {
                log.warn("文件删除失败: {}", fileUrl);
                return Result.error("文件删除失败");
            }
        } catch (Exception e) {
            log.error("文件删除失败: {}, 错误: {}", fileUrl, e.getMessage(), e);
            return Result.error("文件删除失败: " + e.getMessage());
        }
    }
}